using System;
using System.Collections.Generic;
using System.Text;

namespace EuropeEngulfed.NET
{
    abstract class PlayingPiece
    {
        protected MapInfo.CountryID countryOwner;
        private OOSState outOfSupply;
        private bool moved = false;
        public enum OOSState { InSupply, OOS, OOSMoved };

        public bool OutOfSupply
        {
            get
            {
                return outOfSupply != OOSState.InSupply;
            }
        }

        public OOSState OutOfSupplyState
        {
            get
            {
                return outOfSupply;
            }

            set
            {
                outOfSupply = value;
            }
        }

        //This 'Moved' data is not persistent and is only used at runtime to determine whether a piece has been moved
        public bool Moved
        {
            get
            {
                return moved;
            }

            set
            {
                moved = value;
            }
        }

        public virtual MapInfo.CountryID CountryOwner
        {
            get
            {
                return countryOwner;
            }

            set
            {   //A Neutral block or playing piece can be for any country, Also french units change
                if (MapInfo.IsNeutralCountry(value) || value == MapInfo.CountryID.VichyFrance || value == MapInfo.CountryID.FreeFrance || value == MapInfo.CountryID.France)
                    if (MapInfo.IsNeutralCountry(countryOwner) || countryOwner == MapInfo.CountryID.France || countryOwner == MapInfo.CountryID.FreeFrance || countryOwner == MapInfo.CountryID.VichyFrance)
                        countryOwner = value;
            }
        }

        public PlayingPiece(MapInfo.CountryID countryOwner)
        {
            this.countryOwner = countryOwner;
        }

        public PlayingPiece Copy()
        {
            if(this is GroundSupportUnit)
            {
                return ((GroundSupportUnit)this).Copy();
            }
            else if(this is Block)
            {
                return ((Block)this).Copy();
            }
            else
            {
                throw new InvalidOperationException();
            }
        }

        public static PlayingPiece Deserialise(System.Xml.XmlNode node)
        {
            if (node.Name == "GSU")
            {
                return GroundSupportUnit.Deserialise(node);
            }
            else if (node.Name == "Block")
            {
                return Block.Deserialise(node);
            }
            else if(node.SelectSingleNode("GSU") != null)
            {
                return GroundSupportUnit.Deserialise(node.SelectSingleNode("GSU"));
            }
            else if (node.SelectSingleNode("Block") != null)
            {
                return Block.Deserialise(node.SelectSingleNode("Block"));
            }
            else
            {
                throw new InvalidOperationException();
            }
        }

        public string GetTreeViewImageListKey(bool hidden)
        {
            if (this is GroundSupportUnit)
                return Enum.GetName(this.countryOwner.GetType(), this.countryOwner) + "GSU";
            else if (this is Block)
            {
                if (hidden)
                    return Enum.GetName(this.countryOwner.GetType(), this.countryOwner) + "block";
                else
                    return Enum.GetName(this.countryOwner.GetType(), this.countryOwner) + "block" + Enum.GetName(((Block)this).getBlockType().GetType(), ((Block)this).getBlockType()) + ((Block)this).MaxStrength.ToString() + ((Block)this).CurrentStrength.ToString();
            }
            else if (this is FleetPoint)
                return Enum.GetName(this.countryOwner.GetType(), this.countryOwner) + "Fleet";
            else
                throw new NotImplementedException();
        }

        public abstract bool Equals(PlayingPiece playingPiece);

        public abstract string GetDescription();

        public abstract bool CanDoDoubleMovement();

        public abstract string GetHiddenStringDescription();
    }
}
